import { useXAgent, useXChat, Sender, Bubble, XProvider, XRequest } from '@ant-design/x';
import type { BubbleProps } from '@ant-design/x';
import { Card, Flex, Typography, type GetRef } from 'antd';
import { useState, useRef } from 'react';

import markdownit from 'markdown-it'


import './index.scss';

import { OpenAIOutlined, UserOutlined } from '@ant-design/icons';

const md = markdownit({ html: true, breaks: true });

const ROLE_ENUM = {
  SYSTEM: 'system',
  USER: 'user',
}


const { create } = XRequest({
  baseURL: `${import.meta.env.VITE_API_URL}/chat/completions`,
  dangerouslyApiKey: import.meta.env.VITE_API_KEY,
  model: 'qwen-plus',
});

const historyMessages: any[] = []

const insertHistoryMessage = (message: any) => {
  historyMessages.push(message)
}


const renderMarkdown: BubbleProps['messageRender'] = (content) => {
  console.log('content', content);
  return (
    <Typography>
      {/* biome-ignore lint/security/noDangerouslySetInnerHtml: used in demo */}
      <div dangerouslySetInnerHTML={{ __html: md.render(content) }} />
    </Typography>
  );
};

const Chat = () => {
  /** 发送按钮 相关 */
  const senderRef = useRef<GetRef<typeof Sender>>(null);
  const senderBlur = () => senderRef.current!.blur();
  /** 发送按钮 相关 */

  const [isSending, setIsSending] = useState(false);

  const [agent] = useXAgent({
    request: async (info, callbacks) => {
      const { message } = info;
      const { onUpdate } = callbacks;

      // current message
      console.log('message', message);
      insertHistoryMessage(message)
      // messages list
      console.log('%c [ messages ]: ', 'color: #fff; background: red; font-size: 13px;', 'messages', info) 

      let content: any = '';

      try {
        create(
          {
            messages: [{ role: ROLE_ENUM.SYSTEM, content: '你是一个幽默开朗的AI助手，请回答用户的问题。用中文回答' }, ...historyMessages],
            stream: true,
          },
          {
            onSuccess: (chunks) => {
              console.log('sse chunk list', chunks);
              setIsSending(false);
            },
            onError: (error) => {
              console.log('error', error);
            },
            onUpdate: (chunk) => {
              console.log('sse object', chunk);


              if (/\[DONE\]/.test(chunk.data)) {
                insertHistoryMessage({
                  role: ROLE_ENUM.SYSTEM,
                  content: content,
                })
                return;
              }

              const data = JSON.parse(chunk.data);

              content += data?.choices[0].delta.content;

              onUpdate(content);
            },
          },
        );
      } catch (error) {}
    },
  });

  const {
    // use to send message
    onRequest,
    // use to render messages
    messages,
  } = useXChat({
    agent,
    /** 对ai发送的消息转换 */
    transformMessage: (info) => {
      return {
        content: info?.chunk || '',
        role: ROLE_ENUM.SYSTEM,
      } as any
    },
  });

  const [inputValue, setInputValue] = useState('');

  /** 发送消息 */
  const handleSend = () => {
    setIsSending(true);
    onRequest({
      stream: true,
      message: {
        role: ROLE_ENUM.USER,
        content: inputValue,
      },
    });
    senderBlur();
    setInputValue('');
  }

  /** 消息列表 */
  const items = messages.map((item) => {
    const { role, content } = item.message as any
    const isSystem = role === ROLE_ENUM.SYSTEM
    const avatarIcon = isSystem ? <OpenAIOutlined /> : <UserOutlined />
    const placement = isSystem ? 'start' : 'end'
    return {
      key: item.id,
      content,
      avatar: {
        icon: avatarIcon,
        style: {
          backgroundColor: isSystem ? '#1677ff' : '#ff4d4f',
        }
      },
      placement,
      className: 'item-message',
      messageRender: renderMarkdown,
    }
  });

  return (
    <div className="G-chat-container">
      <Card style={{ height: '100%' }}>
        <XProvider>
          <Flex style={{ height: '100%' }} gap={12}>
            <Flex vertical style={{ flex: 1 }} gap={8}>
              {/* 消息列表 */}
              <Bubble.List style={{ flex: 1 }} items={items as any} />
              {/* 输入模块 */}
              <Sender value={inputValue} onChange={setInputValue} onSubmit={handleSend} ref={senderRef} loading={isSending} />
            </Flex>
          </Flex>
        </XProvider>
      </Card>
    </div>
  );
};

export default Chat;